package com.huqing.icu.service.app.impl;

import com.huqing.icu.base.PageDto;
import com.huqing.icu.base.PagingDto;
import com.huqing.icu.base.redis.annotation.RedisLock;
import com.huqing.icu.constants.CacheLockConstants;
import com.huqing.icu.dao.HouseDao;
import com.huqing.icu.dao.HouseInteractionPanelDao;
import com.huqing.icu.dao.HouseUserActionRecordDao;
import com.huqing.icu.dto.HouseDto;
import com.huqing.icu.enums.UserActionTypeEnum;
import com.huqing.icu.inout.in.app.UserFavoriteHouseReq;
import com.huqing.icu.inout.in.app.UserLikeHouseReq;
import com.huqing.icu.inout.out.app.AppHouseListResp;
import com.huqing.icu.model.House;
import com.huqing.icu.model.HouseUserActionRecord;
import com.huqing.icu.service.UserHouseRelationService;
import com.huqing.icu.service.app.IAppHouseService;
import com.huqing.icu.utils.PageUtils;
import com.huqing.icu.utils.ParamValidateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;


/**
 * 用户关联房子接口
 *
 * @author huqing
 * @date 2024-10-20 12:27
 */
@Service
public class UserHouseRelationServiceImpl implements UserHouseRelationService {
    @Autowired
    private HouseDao houseDao;

    @Autowired
    private HouseUserActionRecordDao userActionRecordDao;
    @Autowired
    private HouseInteractionPanelDao houseInteractionPanelDao;
    @Autowired
    private IAppHouseService iAppHouseService;

    /**
     * 喜欢房源
     *
     * @param userLikeHouseReq
     * @return
     */
    @RedisLock(key = CacheLockConstants.HousePrefix.USER_LIKE_HOUSE, waitTime = 3000)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer likeHouse(UserLikeHouseReq userLikeHouseReq) {
        //1、查询房子
        House house = checkHouseExists(userLikeHouseReq.getHouseId());

        Long userId = userLikeHouseReq.getUserId();
        Long houseId = userLikeHouseReq.getHouseId();

        //2、查询点赞行为是否存在
        HouseUserActionRecord userLikeRecord = userActionRecordDao.selectOneByUserId(userId, houseId, UserActionTypeEnum.LIKE.getCode());

        //2.2、如果点赞行为存在，则取消点赞：改成已删除
        if (userLikeRecord != null) {
            //删除点赞行为
            userActionRecordDao.deleteById(userLikeRecord.getId());

            //房子点赞数 -1
            houseInteractionPanelDao.decrActualLikeCount(houseId);
            return 1;
        }

        //3、保存用户点赞房源的行为
        userActionRecordDao.insertLikeRecord(userId, houseId, house.getTitle());

        //3.2 房子点赞数 +1
        houseInteractionPanelDao.incrActualLikeCount(houseId);
        return 1;
    }

    /**
     * 收藏房源
     *
     * @param userFavoriteHouseReq
     * @return
     */
    @RedisLock(key = CacheLockConstants.HousePrefix.USER_FAVORITE_HOUSE, waitTime = 3000)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer favoriteHouse(UserFavoriteHouseReq userFavoriteHouseReq) {
        //1、查询房子
        House house = checkHouseExists(userFavoriteHouseReq.getHouseId());
        Long userId = userFavoriteHouseReq.getUserId();
        Long houseId = userFavoriteHouseReq.getHouseId();

        //2、先查下收藏行为是否存在
        HouseUserActionRecord userFavoriteRecord = userActionRecordDao.selectOneByUserId(userId, houseId, UserActionTypeEnum.FAVORITE.getCode());

        //1.2 如果收藏行为存在，则取消收藏：改成已删除
        if (userFavoriteRecord != null) {
            //删除收藏行为
            userActionRecordDao.deleteById(userFavoriteRecord.getId());

            //房子收藏数 -1
            houseInteractionPanelDao.decrActualFavoriteCount(houseId);
            return 1;
        }

        //2、保存用户收藏房源的行为
        userActionRecordDao.insertFavoriteRecord(userId, houseId, house.getTitle());

        //房子收藏数 +1
        houseInteractionPanelDao.incrActualFavoriteCount(houseId);
        return 1;
    }

    /**
     * 查询我喜欢的房源列表
     *
     * @param userId
     * @return
     */
    @Override
    public PagingDto<AppHouseListResp> queryMyLike(PageDto pageDto, Long userId) {

        int startIndex = PageUtils.getPageStartIndex(pageDto.getPageIndex(), pageDto.getPageSize());

        //1、查询满足条件有多少个
        Integer count = userActionRecordDao.getHouseNumByUserId(userId, UserActionTypeEnum.LIKE.getCode());
        if (count == 0) {
            return new PagingDto(Collections.emptyList(), 0, 0);
        }

        //2、查询房源列表
        List<HouseDto> houseDtoList = userActionRecordDao.selectHouseByUserId(userId, UserActionTypeEnum.LIKE.getCode(), startIndex, pageDto.getPageSize());

        //2.2、关联房源详情
        List<AppHouseListResp> houseRespList = iAppHouseService.linkHouseData(houseDtoList, userId);

        PagingDto pagingDto = new PagingDto<>(houseRespList, PageUtils.getTotalPage(count, pageDto.getPageSize()), count);
        return pagingDto;

    }

    /**
     * 查询我收藏的房源列表
     *
     * @param userId
     * @return
     */
    @Override
    public PagingDto<AppHouseListResp> queryMyFavorite(PageDto pageDto, Long userId) {
        int startIndex = PageUtils.getPageStartIndex(pageDto.getPageIndex(), pageDto.getPageSize());

        //1、查询满足条件有多少个
        Integer count = userActionRecordDao.getHouseNumByUserId(userId, UserActionTypeEnum.FAVORITE.getCode());
        if (count == 0) {
            return new PagingDto(Collections.emptyList(), 0, 0);
        }

        //2、查询房源列表
        List<HouseDto> houseDtoList = userActionRecordDao.selectHouseByUserId(userId, UserActionTypeEnum.FAVORITE.getCode(), startIndex, pageDto.getPageSize());

        //2.2、关联房源详情
        List<AppHouseListResp> houseRespList = iAppHouseService.linkHouseData(houseDtoList, userId);

        PagingDto pagingDto = new PagingDto<>(houseRespList, PageUtils.getTotalPage(count, pageDto.getPageSize()), count);
        return pagingDto;
    }

    /**
     * 增加评论
     *
     * @param userId
     * @param houseId
     * @return
     */
    @Override
    public Integer incrCommentCount(Long userId, Long houseId) {

        return houseInteractionPanelDao.incrActualCommentCount(houseId);
    }

    /**
     * 减少评论数
     *
     * @param userId
     * @param houseId
     * @param count   可能删除评论之后，连带着底下好多评论都被删除
     * @return
     */
    @Override
    public Integer decrActualCommentCount(Long userId, Long houseId, Integer count) {
        Integer result = houseInteractionPanelDao.decrActualCommentCount(houseId, count);
        return 1;
    }


    /**
     * 检查房源是否存在
     *
     * @param houseId
     * @return
     */
    House checkHouseExists(Long houseId) {
        House house = houseDao.selectById(houseId);
        if (house == null) {
            ParamValidateUtils.throwInternalErrorExp("房源不存在，请检查参数");
        }
        return house;
    }

}
